package com.xhs.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xhs.entity.StudentEntity;
import com.xhs.service.ExcelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @desc:
 * @projectName: tools-parent
 * @author: xhs
 * @date: 2022/12/3 22:43
 * @version: JDK 1.8
 */
@Slf4j
@Service
public class ExcelServiceImpl implements ExcelService {

    public static Map<String, Object> row1Map() {
        Map<String, Object> row1 = new LinkedHashMap<>();
        row1.put("班级", "3班");
        row1.put("姓名", "张三");
        row1.put("年龄", 20);
        row1.put("成绩", 120);
        row1.put("是否合格", true);
        row1.put("考试日期", new Date());
        return row1;
    }

    public static Map<String, Object> row2Map() {
        Map<String, Object> row2 = new LinkedHashMap<>();
        row2.put("班级", "5班");
        row2.put("姓名", "李四");
        row2.put("年龄", 19);
        row2.put("成绩", 119);
        row2.put("是否合格", true);
        row2.put("考试日期", new Date());
        return row2;
    }

    /**
     * 一级表头
     *
     * @param response
     * @return
     */
    @Override
    public void listExcel(HttpServletResponse response) {
        try {
            //模拟学生数据
            List<StudentEntity> studentList = StudentServiceImpl.getStudentList();
            // 通过工具类创建writer，默认创建xls格式
            ExcelWriter writer = ExcelUtil.getWriter();
            //自定义标题名
            writer.addHeaderAlias("name", "姓名");
            writer.addHeaderAlias("age", "年龄");
            writer.addHeaderAlias("sex", "性别");
            writer.addHeaderAlias("classNmae", "班级");
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(studentList, true);
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            // 这里容易乱码 处理
            String name = URLEncoder.encode("学生统计表", String.valueOf(StandardCharsets.UTF_8));
            // 设置头部
            response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");
            ServletOutputStream out = null;
            try {
                out = response.getOutputStream();
                writer.flush(out, true);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭writer
                writer.close();
            }
            //关闭输出Servlet流
            IoUtil.close(out);
        } catch (UnsupportedEncodingException e) {
            log.info("---------导出失败:{}----------", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 多级表头
     *
     * @param response
     * @return
     */
    @Override
    public void mapExcel(HttpServletResponse response) {
        try {
            Map<String, Object> map1 = row1Map();
            Map<String, Object> map2 = row2Map();
            // 数据
            List<Map<String, Object>> rows = CollUtil.newArrayList(map1, map2);
            ExcelWriter writer = ExcelUtil.getWriterWithSheet("成绩单");
            // 标题行合并单元格
            writer.merge(map1.size() - 1, "成绩单");
            // 输出Excel
            writer.write(rows, true);
            // response为HttpServletResponse对象
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            // 报表名字中文乱码处理
            String name = URLEncoder.encode("成绩单", String.valueOf(StandardCharsets.UTF_8));
            // 设置头部
            response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");
            // out为OutputStream，需要写出到的目标流
            ServletOutputStream out = null;
            try {
                out = response.getOutputStream();
                writer.flush(out, true);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭writer，释放内存
                writer.close();
            }
            // 此处记得关闭输出Servlet流
            IoUtil.close(out);
        } catch (Exception e) {
            log.info("---------导出失败:{}----------", e.getMessage());
            e.printStackTrace();
        }
    }
}
